/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package utilidades.autocompletar;

import java.util.ArrayList;
import java.util.List;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.control.Tooltip;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Popup;
import javafx.stage.Window;
import javafx.util.Callback;
import transervfx.Dato.Entidad.Cliente;
import transervfx.Dato.Entidad.Localidad;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author rocio
 */
public class TextBoxAutoCompletar<T extends Object> extends HBox {

  
    
    private final static String colorFondoTextoSeleccionado="YELLOW";
    private final static String colorTextoSeleccionado="BLACK";
    
   
    private final TextField text = new TextField();
    private final Button boton = new Button("\\/");
    private List<T> datosTotalesCombobox = new ArrayList();
    private ObservableList<T> datosRestingidoList = FXCollections.observableArrayList();
    private ListView<T> listView = new ListView();
    private Popup popup = new Popup();
    private final ChangeListener<String> escucharImput = new ChangeListener<String>() {
        @Override
        public void changed(ObservableValue ov, String t, String t1) {

            showPopup();
            //System.out.println("cambio el texto en el textfield " + t1);
            
            restringirDatos(t1);
        }
    };

    public TextBoxAutoCompletar() {
        super();

        this.text.setTooltip(new Tooltip(""));
        this.text.idProperty().bind(this.idProperty());
        this.boton.setStyle("-fx-background-radius: 0;");
        
        this.listView.setPrefHeight(100);
       

        this.popup.setAutoHide(true);
        popup.getContent().add(listView);
        datosRestingidoList.addAll(this.datosTotalesCombobox);
        listView.setItems(this.datosRestingidoList);



        listView.addEventFilter(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
            public void handle(KeyEvent t) {
                 if (t.getCode() == KeyCode.ESCAPE) {
                        popup.hide();
                        text.requestFocus();
                    }
                    if (t.getCode() == KeyCode.ENTER) {
                        selectList();
                    } else if (t.getCode() == KeyCode.UP) {
                        
                        if (listView.getSelectionModel().getSelectedIndex() == 0) {                             
                            text.requestFocus();
                        }
                    }/*else if(){
                    
                     }*/
                
            }
        });

        listView.addEventFilter(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() {
            public void handle(MouseEvent t) {
                //System.out.println("mouser");
                selectList();
            }
        });


        text.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
            public void handle(KeyEvent t) { //WHEN USER PRESS DOWN ARROW KEY FOCUS TRANSFER TO LISTVIEW
                if (t.getCode() == KeyCode.DOWN) {
                   // System.out.println("Focused Traversal");
                    showPopup();
                    if (popup.isShowing()) {
                        listView.requestFocus();
                        listView.getSelectionModel().select(0);
                    }
                }
            }
        });

        /*listView.getSelectionModel().selectedItemProperty().addListener(
         new ChangeListener<String>() {
         public void changed(ObservableValue<? extends String> ov, 
         String old_val, String new_val) {
         if(new_val!=null){
         System.out.println("valor seleccionado "+new_val);
                    
         selectList();
         }
         }
         });*/
        this.getChildren().add(text);
        this.getChildren().add(boton);
        boton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                showPopup();
            }
        });

        listView.setCellFactory(
                new Callback<ListView<T>, ListCell<T>>() {
                    @Override
                    public ListCell<T> call(ListView<T> param) {
                        final ListCell<T> cell = new ListCell<T>() {
                            private HBox celda;
                            {
                                
                                setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                                celda=new HBox();
                            }

                            @Override
                            public void updateItem(T item,
                                    boolean empty) {
                                super.updateItem(item, empty);
                               
                                if (item == null || empty) {
                                   celda.getChildren().clear();
                                    return;
                                }
                               
                                if (item != null) {
                                  
                                    pintarTexto(celda,item.toString().toUpperCase(),text.getText().toUpperCase());
                                    setGraphic(celda);
                                 
                                }                         
                            }
                        };
                        return cell;
                    }
                });


        text.textProperty().addListener(escucharImput);

    }

    private Window getWindow() {
        return this.text.getScene().getWindow();
    }

    public void showPopup() {
        listView.setPrefWidth(text.getWidth() + boton.getWidth());
        popup.show(
                getWindow(),
                getWindow().getX() + text.localToScene(0, 0).getX() + text.getScene().getX(),
                getWindow().getY() + text.localToScene(0, 0).getY() + text.getScene().getY() + text.getHeight());
        //getWindow().getX()+dimen.getWidth()+WINDOW_BORDER,
        //getWindow().getY()+dimen.getHeight()+TITLE_HEIGHT); 

        listView.getSelectionModel().clearSelection();
        listView.getFocusModel().focus(-1);
    }

    private void restringirDatos(String t1) {
        this.datosRestingidoList.clear();
        t1 = t1.toUpperCase();
        String s;
        for (T t : this.datosTotalesCombobox) {
            s=t.toString();
            if (s.toUpperCase().contains(t1)) {
                //System.out.println("lo contiende");

                datosRestingidoList.add(t);
            }
        }
    }

   

    public void selectList() {
        Object i = listView.getSelectionModel().getSelectedItem();
        if (i != null) {
            text.textProperty().removeListener(this.escucharImput);
            text.setText(listView.getSelectionModel().getSelectedItem().toString());

            text.requestFocus();
            text.requestLayout();
            text.end();
            popup.hide();
            text.textProperty().addListener(escucharImput);
            //textbox.setPromptText("");
        }
    }
    
     private void pintarTexto(HBox h,String contenido, String itemSeleccionado){
       
        h.getChildren().clear();
        int tamTextSelect=itemSeleccionado.length();
        int ini=0;
        int i=contenido.indexOf(itemSeleccionado);
        int fin=contenido.length();
      //  System.out.println("tamTextSelect: "+tamTextSelect+" INI "+ini+" i: "+i+" fin: "+fin);
        //si encontro el item
        if(i>-1){
         //   System.out.println("1LO CONTIENE");
            //si es el inicio
            if(i==ini){
            //    System.out.println("2ES EL INICIO");
                Label t=new Label(contenido.substring(ini, ini+tamTextSelect));
               t.setStyle("-fx-text-fill: "+colorTextoSeleccionado+";-fx-background-color: "+this.colorFondoTextoSeleccionado+";");
                //t.setFill(Color.RED);
                h.getChildren().add(t);
                //listR.add(contenido.substring(ini, ini+tamTextSelect));
                if(tamTextSelect==fin) {
                //    System.out.println("3ES EL FINAL");
                    return;
                }
               // System.out.println("4NO ES EL FINAL");
                 h.getChildren().add(new Text(contenido.substring(ini+tamTextSelect, fin)));
                //listR.add(contenido.substring(ini+tamTextSelect, fin));
            }
            else{
              //  System.out.println("5 NO ES EL INICIO");
                h.getChildren().add(new Text(contenido.substring(ini, i)));
              //  listR.add(contenido.substring(ini, i));
                Label t=new Label(contenido.substring(i, i+tamTextSelect));
               t.setStyle("-fx-text-fill: "+colorTextoSeleccionado+";-fx-background-color: "+colorFondoTextoSeleccionado+";");
                //t.setFill(Color.RED);
                h.getChildren().add(t);
               // h.getChildren().add(new Text(contenido.substring(i, i+tamTextSelect)));
                //listR.add(contenido.substring(i, i+tamTextSelect));
                 if(i+tamTextSelect==fin) {
              //       System.out.println("6 ES EL FINAL");
                    return ;
                }
                 // System.out.println("7 NO ES EL FINAL");
                  h.getChildren().add(new Text(contenido.substring(i+tamTextSelect, fin)));
               // listR.add(contenido.substring(i+tamTextSelect, fin));              
            }
           
        }
        else{
            h.getChildren().add(new Text(contenido));
        }
       
 
    }

   

    public void setText(String text) {
        this.text.setText(text);
         popup.hide();
    }

    public String getText() {
       return this.text.getText();
    }

    public ObservableList<T> getList() {
        return datosRestingidoList;
    }
    
    public void setData(ObservableList<T> list){
        this.datosTotalesCombobox=list;
        datosRestingidoList.clear();
        datosRestingidoList.addAll(list);
    }

    public void setData(List<T> list) {
        this.setText("");
        this.datosTotalesCombobox=list;
        datosRestingidoList.clear();
        datosRestingidoList.addAll(list);
    }

   
    
    public T getValue(){
        T item=this.listView.getSelectionModel().getSelectedItem();
        String t=this.text.getText().toUpperCase();
        if(item!=null & !t.isEmpty()){
        if(item.toString().toUpperCase().equals(t)) {
            return item;
        }
        }
        else{
            if(!t.isEmpty()){
                for(T i: listView.getItems()){
                    if(i.toString().toUpperCase().equals(t)) {
                        return i;
                    }
                }
            }
        }
        
        return null;
    }

    public StringProperty textProperty() {
        return this.text.textProperty();
        
    }

    public TextField getTextField() {
        return this.text;
    }

    public void seleccionar(T data) {
       if(!this.listView.getItems().isEmpty()){
           this.listView.getSelectionModel().select(data);
           this.text.setText(data.toString());
           this.popup.hide();
       }
    }

    public void addListener(ChangeListener<T> changeListener) {
        this.listView.getSelectionModel().selectedItemProperty().addListener(changeListener);
        
    }
    
    public void removeListener(ChangeListener<T> changeListener) {
        this.listView.getSelectionModel().selectedItemProperty().removeListener(changeListener);
        
    }

    
   

   
}

